﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Bambit.XmlRpc
{
	/// <summary>
	/// An <see cref="RpcStruct"/> contains an array of <see cref="Member">Members</see>
	/// </summary>
	[XmlType]
	[Serializable]
	public class RpcStruct 
	{
		#region Class Data
		private Dictionary<string, Member> _Members;
		#endregion

		#region Ctor

		/// <summary>
		/// Initializes a new instance of the <see cref="RpcStruct"/> class.
		/// </summary>
		public RpcStruct()
		{
			_Members = new Dictionary<string, Member>();
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the members.
		/// </summary>
		/// <value>The members of this <see cref="RpcStruct"/>.</value>
		[XmlElement("member")]
		public Member[] Members
		{
			get
			{
				Member[] members = new Member[_Members.Count];
				_Members.Values.CopyTo(members, 0);
				return members;
			}
			set
			{
				_Members = new Dictionary<string, Member>(value.Length);
				foreach (Member member in value)
					_Members[member.Name] = member;

			}
		}

		/// <summary>
		/// Gets the <see cref="Member"/> with the specified name.
		/// </summary>
		/// <value>The member in the collection with the specified name.</value>
		public Member this[string name]
		{
			get
			{
				return _Members[name];
			}
		}

		#endregion

		#region Implementation of IEnumerable

		/// <summary>
		///                     Returns an enumerator that iterates through the collection.
		/// </summary>
		/// <returns>
		///                     A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
		/// </returns>
		/// <filterpriority>1</filterpriority>
		public IEnumerator<Member> GetEnumerator()
		{
			return _Members.Values.GetEnumerator();
		}

		#endregion

		#region Methods
		/// <summary>
		/// Adds the specified member to the collection
		/// </summary>
		/// <param name="member">The member to add.</param>
		public void Add(Member member)
		{
			_Members.Add(member.Name, member);
		}
		#endregion

		#region Implementation of IXmlSerializable

		/// <summary>
		///                     This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply the <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute" /> to the class.
		/// </summary>
		/// <returns>
		///                     An <see cref="T:System.Xml.Schema.XmlSchema" /> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)" /> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)" /> method.
		/// </returns>
		public XmlSchema GetSchema()
		{
			throw new System.NotImplementedException();
		}

		/// <summary>
		///                     Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">
		///                     The <see cref="T:System.Xml.XmlReader" /> stream from which the object is deserialized. 
		///                 </param>
		public void ReadXml(XmlReader reader)
		{
			
		}

		/// <summary>
		///                     Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">
		///                     The <see cref="T:System.Xml.XmlWriter" /> stream to which the object is serialized. 
		///                 </param>	
		public void WriteXml(XmlWriter writer)
		{
			XmlSerializer xmlSerializer=new XmlSerializer(typeof(Member));
			foreach (KeyValuePair<string, Member> pair in _Members)
			{
				xmlSerializer.Serialize(writer, pair.Value);
			}
		}

		#endregion
	}
}
